#include "StdAfx.h"
#include "ErrorContainer.h"

ErrorContainer* ErrorContainer::errorContainer = NULL;

ErrorContainer* ErrorContainer::get_instance() {
	// call the constructor for the first time
	// if the object has been created already
	// return reference to the object already created
	if(errorContainer==NULL) errorContainer = new ErrorContainer();
	return errorContainer;
}

ErrorContainer::ErrorContainer(void) {
	errors.clear();
	errorsNum = 0;
	warningsNum = 0;
	failOnWarining = false;
}

ErrorContainer::~ErrorContainer(void)
{
}

void ErrorContainer::addError(ErrorElement err) {
	bool isFind = false;

	for (int i=0;i<(int)errors.size();i++) {
		if(errors.at(i).description == err.description && 
			errors.at(i).errorType == err.errorType && 
			errors.at(i).strinNumber == err.strinNumber) {
				isFind = true;
		}
	}

	if(!isFind) {
		errors.push_back(err);

		if(err.errorType == Warning) {
			warningsNum++;
		} else {
			errorsNum++;
		}
	}
}

void ErrorContainer::addError(ErrorType errType, int errString, string errDescription) {
	ErrorElement new_error;

	new_error.errorType = errType;
	new_error.strinNumber = errString;
	new_error.description = errDescription;

	addError(new_error);
}

void ErrorContainer::addError(ErrorType errType, string errDescription) {
	addError(errType, 0, errDescription);
}

vector<ErrorElement> ErrorContainer::getErrors() {
	return errors;
}

int ErrorContainer::getErrorsNum() {
	return errorsNum;
}

int ErrorContainer::getWarningsNum() {
	return warningsNum;
}

void ErrorContainer::printToCons() {
	cout << endl << endl << endl << endl << "----------" << endl << "errors: " << errorsNum << " warnings: " << warningsNum << endl << "----------" << endl;
	for(int i=0; i < (int)errors.size(); i++) {
		if(errors.at(i).errorType == System) {
			cout << "System";
		} else if(errors.at(i).errorType == Lexical) {
			cout << "Lexical";
		} else if(errors.at(i).errorType == Syntax) {
			cout << "Syntax";
		} else if(errors.at(i).errorType == Semantics) {
			cout << "Semantics";
		} else if(errors.at(i).errorType == Warning) {
			cout << "Warning";
		}
		if(errors.at(i).strinNumber != 0) {
			cout << " at string\t: " << errors.at(i).strinNumber << "\t" << errors.at(i).description << endl;
		} else {
			cout << "\t: " << errors.at(i).description << endl;
		}
	}
}
void ErrorContainer::printToFile(string filePath) {
	ofstream outFS;
	outFS.open(filePath.c_str());
	if(NULL != outFS) {
		for(int i=0; i < (int)errors.size(); i++) {
			if(errors.at(i).errorType == System) {
				outFS << "System";
			} else if(errors.at(i).errorType == Lexical) {
				outFS << "Lexical";
			} else if(errors.at(i).errorType == Syntax) {
				outFS << "Syntax";
			} else if(errors.at(i).errorType == Semantics) {
				outFS << "Semantics";
			} else if(errors.at(i).errorType == Warning) {
				outFS << "Warning";
			}
			if(errors.at(i).strinNumber != 0) {
				outFS << " at string\t: " << errors.at(i).strinNumber << "\t" << errors.at(i).description << endl;
			} else {
				outFS << "\t: " << errors.at(i).description << endl;
			}
		}
	}
	outFS.close();
}

void ErrorContainer::setFlags(bool failOnWarining) {
	this->failOnWarining = failOnWarining;
}

bool ErrorContainer::check(){
	if(failOnWarining && warningsNum > 0) {
		return false;
	}
	if(errorsNum > 0) {
		return false;
	}

	return true;
}